﻿using System;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;
using System.Net;
using ApplLogic.ApplClasses;
using ApplLogic.LogicalServices;
using ApplLogic.Server;
using ConnectionObjects;
using Utilities.GlobalData;

namespace ApplLogic.ServerLogic
{
    public class Server
    {
        private TcpListener m_TcpListener;
        private Thread m_ListenThread;
        int m_SerialNumber = 1;
        
        public Server()
        {
            m_TcpListener = new TcpListener(IPAddress.Any, 450);
            m_ListenThread = new Thread(new ThreadStart(listenForClients));
            m_ListenThread.Start();
        }

        private void listenForClients()
        {
            m_TcpListener.Start();
            while (true)
            {
                TcpClient client = m_TcpListener.AcceptTcpClient();
                Thread clientThread = new Thread(new ParameterizedThreadStart(handleClientComunication));
                clientThread.Start(client);
            }
        }

        private void handleClientComunication(Object clientAsObj)
        {
            TcpClient client = clientAsObj as TcpClient;
            eWorkingWithServerType type = handleLogin(client);
            if (type != eWorkingWithServerType.None) // if login was successfull 
            {
                ClientComunicationHandler cch = createComunicationHandler(client, type);
                Console.WriteLine("Client number: " + m_SerialNumber + " connected as type " + type);
                m_SerialNumber++;
                cch.HandleClientComm();
            }
        }

        private eWorkingWithServerType handleLogin(TcpClient client)
        {
            ApplLoginHandler loginHandler = new ApplLoginHandler(client);
            eWorkingWithServerType typeThatLoggedIn = loginHandler.HandleLogin();
            return typeThatLoggedIn;
        }

        private ClientComunicationHandler createComunicationHandler(TcpClient client, eWorkingWithServerType type)
        {
            ClientComunicationHandler handler = null;
            switch (type)
            {
                case eWorkingWithServerType.Manager:
                    handler = new ClientManagerComunicationHandler(client, m_SerialNumber, ApplRequestHandlerAbstract.FactoryMethod(type));
                    break;
                case eWorkingWithServerType.Worker:
                    handler = new ClientWorkerComunicationHandler(client, m_SerialNumber, ApplRequestHandlerAbstract.FactoryMethod(type));
                    break;
            }
            return handler;
        }
    }

}

